﻿using CPPEI.Coolzon.Common;
using CPPEI.Coolzon.Event.NCL;
using CPPEI.Coolzon.Service.Contract;
using CPPEI.Coolzon.UI.Data;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace CPPEI.Coolzon.UI.Views.EventProxies
{
    public class RespOpenSceneHandler : BaseResponseHandler<RespOpenSceneData>
    {
        private static Thread s_openSceneSequenceThread = null;
        private static long? s_latestOpenTicks = null;
        private static List<RespOpenSceneData> s_sequenceDataList = new List<RespOpenSceneData>();
        private static object s_lockObj = new object();
        private static RemoteEventProxy s_remoteEventProxy;

        protected override void OnHandle(RemoteEventProxy remoteEventProxy, ServiceProxy.MainServiceRef.Response response, RespOpenSceneData responseData)
        {
            Common.Logger.DebugToTag("RespOpenSceneHandler", "开始处理事件-打开 scene:{0}", responseData.SceneName);

            s_remoteEventProxy = remoteEventProxy;

            if (string.Equals(UIContext.Current.AppType, "DISPLAYAPP", StringComparison.CurrentCultureIgnoreCase))
            {
                if (UIContext.Current.IsLoadingSolution)
                {
                    //展示端正在加载方案时，不执行操作
                    Coolzon.Common.Logger.WarningToTag("RespOpenSceneHandler", "接收到RespSwitchSolutionData数据要求切换到场景：{0}，但是本地正在加载方案，不执行操作", responseData.SceneName);
                    return;
                }
                if (!UIContext.Current.IsUnderControl)
                {
                    // 展示端且不在控制模式下，不处理来自服务器的切换事件
                    return;
                }
            }

            if (remoteEventProxy.RenderView != null)
            {
                if (s_latestOpenTicks == null)
                {
                    // 直接打开
                    Common.Logger.WarningToTag("RespOpenSceneHandler", "直接打开 scene:{0}", responseData.SceneName);
                    NCLOpenSceneEvent @event = null;
                    Coolzon.UI.Data.OpenSceneArgs args = Coolzon.UI.Data.OpenSceneArgs.BuildFromString(responseData.ParameterString);
                    if (responseData.SwitchMode == SwitchMode.Replace.ToString())
                    {
                        remoteEventProxy.RenderView.OpenScene(SwitchMode.Replace, responseData.FrameName, "", responseData.SceneName, args);
                        @event = new NCLOpenSceneEvent(SwitchMode.Replace, responseData.FrameName, responseData.SceneName, args);

                    }
                    else
                    {
                        remoteEventProxy.RenderView.OpenScene(SwitchMode.Pop, responseData.FrameName, "", responseData.SceneName, args);
                        @event = new NCLOpenSceneEvent(SwitchMode.Pop, responseData.FrameName, responseData.SceneName, args);
                    }

                    @event.State = NCLEventState.Finished;
                    NCLEventBus.PublishAsync(@event);
                    Common.Logger.DebugToTag("RespOpenSceneHandler", "发送事件-打开 scene:{0}", responseData.SceneName);
                    s_latestOpenTicks = DateTime.Now.Ticks;
                }
                else 
                {
                    if (DateTime.Now.Ticks - s_latestOpenTicks >= TimeSpan.FromSeconds(3).Ticks)
                    {
                        // 本次和上次相差3秒以上，直接打开
                        Common.Logger.WarningToTag("RespOpenSceneHandler", "本次和上次相差3秒以上，直接打开 scene:{0}", responseData.SceneName);
                        NCLOpenSceneEvent @event = null;
                        Coolzon.UI.Data.OpenSceneArgs args = Coolzon.UI.Data.OpenSceneArgs.BuildFromString(responseData.ParameterString);
                        if (responseData.SwitchMode == SwitchMode.Replace.ToString())
                        {
                            remoteEventProxy.RenderView.OpenScene(SwitchMode.Replace, responseData.FrameName, "", responseData.SceneName, args);
                            @event = new NCLOpenSceneEvent(SwitchMode.Replace, responseData.FrameName, responseData.SceneName, args);
                        }
                        else
                        {
                            remoteEventProxy.RenderView.OpenScene(SwitchMode.Pop, responseData.FrameName, "", responseData.SceneName, args);
                            @event = new NCLOpenSceneEvent(SwitchMode.Pop, responseData.FrameName, responseData.SceneName, args);
                        }

                        @event.State = NCLEventState.Finished;
                        NCLEventBus.PublishAsync(@event);
                        Common.Logger.DebugToTag("RespOpenSceneHandler", "发送事件-打开 scene:{0}", responseData.SceneName);
                        s_latestOpenTicks = DateTime.Now.Ticks;
                    }
                    else
                    {
                        lock (s_lockObj)
                        {
                            Common.Logger.WarningToTag("RespOpenSceneHandler", "添加到运行队列 scene:{0}", responseData.SceneName);
                            s_sequenceDataList.Add(responseData);
                        }
                        if (s_openSceneSequenceThread == null)
                        {
                            // 间隔时间太短，开启队列处理线程，按顺序执行打开操作
                            s_openSceneSequenceThread = new Thread(Run);
                            s_openSceneSequenceThread.Start();

                            Common.Logger.WarningToTag("RespOpenSceneHandler", "请求收到太快，启动队列处理线程");
                        }
                    }
                }
            }
            else
            {
                NCLOpenSceneEvent @event = null;
                Coolzon.UI.Data.OpenSceneArgs args = Coolzon.UI.Data.OpenSceneArgs.BuildFromString(responseData.ParameterString);
                if (responseData.SwitchMode == SwitchMode.Replace.ToString())
                {
                    @event = new NCLOpenSceneEvent(SwitchMode.Replace, responseData.FrameName, responseData.SceneName, args);
                }
                else
                {
                    @event = new NCLOpenSceneEvent(SwitchMode.Pop, responseData.FrameName, responseData.SceneName, args);
                }
                NCLEventBus.PublishAsync(@event);
                Common.Logger.DebugToTag("RespOpenSceneHandler", "发送事件-打开 scene:{0}", responseData.SceneName);

                // 界面还没有构造出来，收到了打开请求，这个时候将会显示出黑色的屏幕，
                // 需要发出一次同步视图状态的请求到服务器，等服务器回应之后应该可以显示出画面了
                UI.UIContext.Current.IsNeesSyncViewStateWhenEnterDomain = true;
            }
        }

        private static void Run()
        {
            for (int index = 0; index < s_sequenceDataList.Count;)
            {
                RespOpenSceneData responseData = s_sequenceDataList[index];
                lock (s_lockObj)
                {
                    s_sequenceDataList.RemoveAt(index);
                    Common.Logger.WarningToTag("RespOpenSceneHandler", "启动队列处理线程处理操作，剩余:{0}", s_sequenceDataList.Count);
                }
                //else
                //{ 
                //    index++;
                //}
                // 执行此操作

                NCLOpenSceneEvent @event = null;
                Coolzon.UI.Data.OpenSceneArgs args = Coolzon.UI.Data.OpenSceneArgs.BuildFromString(responseData.ParameterString);
                if (responseData.SwitchMode == SwitchMode.Replace.ToString())
                {
                    s_remoteEventProxy.RenderView.OpenScene(SwitchMode.Replace, responseData.FrameName, "", responseData.SceneName, args);
                    @event = new NCLOpenSceneEvent(SwitchMode.Replace, responseData.FrameName, responseData.SceneName, args);
                }
                else
                {
                    s_remoteEventProxy.RenderView.OpenScene(SwitchMode.Pop, responseData.FrameName, "", responseData.SceneName, args);
                    @event = new NCLOpenSceneEvent(SwitchMode.Pop, responseData.FrameName, responseData.SceneName, args);
                }

                @event.State = NCLEventState.Finished;
                NCLEventBus.PublishAsync(@event);
                Common.Logger.DebugToTag("RespOpenSceneHandler", "发送事件-打开 scene:{0}", responseData.SceneName);
                s_latestOpenTicks = DateTime.Now.Ticks;

                // 停止3秒
                Thread.Sleep(3000);
            }
            s_openSceneSequenceThread = null;
            Common.Logger.WarningToTag("RespOpenSceneHandler", "启动队列处理线程guanbi");
        }
    }
}
